﻿using System;
using System.Diagnostics;
using Moq;
using NUnit.Framework;
using SvnDeploy.Service.Cfg;

namespace SvnDeploy.Service.Impl
{
    [TestFixture]
    public class DeploymentWorkerImplTests
    {
        private SvnDeployConfigurationSection configuration;
        private IDeploymentWorker deploymentWorker;
        private Mock<ILog> log;
        private Mock<IVirtualDirectoryUpdater> virtualDirectoryUpdater;

        [SetUp]
        public void BeforeEachTest()
        {
            log = new Mock<ILog>();
            virtualDirectoryUpdater = new Mock<IVirtualDirectoryUpdater>();
            configuration = new SvnDeployConfigurationSection();
            deploymentWorker = new DeploymentWorkerImpl(virtualDirectoryUpdater.Object, log.Object, configuration);
        }

        [Test]
        public void Deploy_RunsUpdaterForEachApplication()
        {            
            configuration.Applications.Add(new ApplicationElement { Name = "test", SvnPath = "file:///server/project/path", VirtualDirectory = @"C:\" });

            deploymentWorker.Deploy();

            virtualDirectoryUpdater.Verify(x => x.CheckOutOrUpdate("test", "file:///server/project/path", @"C:\"), Times.Exactly(1));
        }

        [Test]
        public void Deploy_ShouldWriteToLog()
        {
            deploymentWorker.Deploy();
            log.Verify(x => x.Write(It.IsAny<string>(), It.IsAny<EventLogEntryType>()), Times.Once());
        }

        [Test]
        public void Deploy_WhenThrowsException_ShouldWriteError()
        {
            configuration.Applications.Add(new ApplicationElement { Name = "test", SvnPath = "file:///server/project/path", VirtualDirectory = @"C:\" });
            virtualDirectoryUpdater.Setup(x => x.CheckOutOrUpdate(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>())).Throws(new Exception());
            deploymentWorker.Deploy();
            log.Verify(x => x.Write(It.IsAny<string>(), EventLogEntryType.Error));
        }

        private void SetConfiguration(int numberOfApplications = 1)
        {
            for (int i = 0; i < numberOfApplications; i++)
            {
                configuration.Applications.Add(new ApplicationElement { Name = Guid.NewGuid().ToString() });
            }
        }
    }
}
